package com.niodata.dp.expression.function.array;

import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorObject;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public class ArraySliceFunction extends AbstractFunction {

  @Override
  public String getName() {
    return "array.slice";
  }

  /**
   * slice list or array.
   *
   * @param env env
   * @param array array
   * @param start start index,from 0（include）,支持负数，表示从后往前计算
   * @param end end index(exclude)，支持负数，表示从后往前计算，若为负数，则包含该index
   */
  public AviatorObject call(Map<String, Object> env, AviatorObject array, AviatorObject start,
        AviatorObject end) {
    Object v = array.getValue(env);
    Object[] varray = null;
    if (List.class.isAssignableFrom(v.getClass())) {
      List list = (List) v;
      varray = list.toArray(new Object[list.size()]);
    } else if (v.getClass().isArray()) {
      int len = Array.getLength(v);
      varray = new Object[len];
      for (int i = 0; i < len; i++) {
        varray[i] = Array.get(v, i);
      }
    }
    int index1 = (int) start.getValue(env);
    int index2 = (int) end.getValue(env);
    if (index1 < 0) {
      index1 = varray.length + index1;
    }
    if (index2 < 0) {
      index2 = varray.length + index2 + 1;
    }

    Object[] slice = Arrays.copyOfRange(varray, index1, index2);
    Object result = slice;
    if (List.class.isAssignableFrom(v.getClass())) {
      result = Arrays.asList(slice);
    }
    return FunctionUtils.wrapReturn(result);
  }
}
